package com.zs.main.config;

import com.zs.framework.domain.Result;
import com.zs.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Copyright 2020 ZS Network Co., Ltd. All rights reserved.
 * 本文件仅限于正数网络技术有限公司内部传阅，禁止外泄以及用于其他的商业目的。
 * Created by mao on 2021/7/14
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public Result<Object> handler(Exception e){
        log.error("",e);
        Result<Object> result = new Result<>();
        result.setSuccess(false);
        if (e instanceof BusinessException){
            result.setErrorCode(String.valueOf(((BusinessException) e).getCode()));
            result.setErrorMessage(e.getMessage());
        } else if (e instanceof ConstraintViolationException) {
            String msg = e.getMessage();
            if (msg != null) {
                int lastIndex = msg.lastIndexOf(':');
                if (lastIndex >= 0) {
                    msg = msg.substring(lastIndex + 1).trim();
                }
            }
            result.setErrorMessage(msg);
        } else if (e instanceof BindException){
            BindingResult bindingResult = ((BindException)e).getBindingResult();
            result.setErrorMessage(assembleException(bindingResult.getAllErrors()));
        } else if (e instanceof MethodArgumentNotValidException){
            BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
            result.setErrorMessage(assembleException(bindingResult.getAllErrors()));
        } else if (e instanceof ConstraintViolationException){
            Set<ConstraintViolation<?>> constraintViolations = ((ConstraintViolationException)e).getConstraintViolations();
            String errorMsg = constraintViolations.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(";"));
            result.setErrorMessage(errorMsg);
        } else {
            result.setErrorCode("1010");
            result.setErrorMessage("系统错误");
        }
        return result;
    }

    private  String assembleException(List<ObjectError> errorList) {
        StringBuilder errorMsg = new StringBuilder();
        for (ObjectError objectError : errorList) {
            errorMsg.append(objectError.getDefaultMessage()).append(";");
        }
        errorMsg.delete(errorMsg.length() - 1, errorMsg.length());
        return errorMsg.toString();
    }
}
